/**
 * @author lonun
 * @blog http://www.lonun.com
 */

var http = require('http'), 
	sio = require('socket.io'),
	formidable = require('formidable'), 
	url = require("url"),
	path = require("path"), 
	fs = require("fs"),
	querystring = require("querystring"), 
	util = require('util'),
	appUtil = require('./util'), 
	config = require('../config'),
	contentTypes = require('./contentTypes'),
	WebForm = require('./webform'),
	ViewEngine = require('./view').ViewEngine,
	Session = require('./session').Session,
	SessionManager = require('./session').SessionManager,
	ApplicationContext = require('./appContext').ApplicationContext,
	httpHandler = require('./httpHandler'), 
	SocketProcess = require('./SocketProcess').SocketProcess,
	route = require('./route');

var socket = 'off';

Array.prototype.each=function(callback){
    for (var i=0;i<this.length;i++){
       callback.apply(this[i]);
    }
}

exports.enableSocket = function() {
	socket = 'on';
	return this;
}

exports.createServer = function(port) {
	port = port || config.defaultPort;
	var context = new ApplicationContext();
	var sessionMgr = new SessionManager();
	var server = http.createServer(function(req, res) {
		var url = req.url;
		var clientIP = req.headers['x-forwarded-for']
				|| req.connection.remoteAddress;
		if (url == '/') {
			url = config.indexPage;
		}
		var suffix = path.extname(url);
		if (contentTypes.contentTypes[suffix]) {// 静态文件直接返回
			httpHandler.handleStaticFile(req, res);
			return;
		}
		var webForm = route.getWebForm(url);
		if(webForm==null){//没有找到webForm时返回404
			httpHandler.handleHtmlFile(res, config.err404Page);
			return;
		}
		if (contentTypes.htmlContentTypes[suffix]) {// html文件直接返回
			httpHandler.handleHtmlFile(req, res, webForm);
			return;
		}
		
		var httpCookie = req.headers.cookie;
		var cookie;
		var sessionID;
		var session;
		if(httpCookie){//获取cookie，并存入webForm
			cookie = appUtil.parseCookie(req.headers.cookie);
			sessionID = cookie.sessionID;
		}
		//session与cookie处理
		if(sessionID){//判断sessionid是否合法
			var lastTime = sessionID.split('_')[1];
			sessionID = sessionID.split('_')[0];
			session = sessionMgr.getSession(sessionID);
			if(session){
				if(session.getRefreshTime()==lastTime){//判断时间戳是否合法，并将新的时间戳更新到cookie
					session.refresh();
				}else{//时间戳不对，session非法。
					sessionMgr.remove(sessionID);
					console.log('session非法！ip:'+clientIP);
					//handlerError({title:'session非法', msg:'session非法，请重新登录！'}, res);
					session = sessionMgr.create();
					sessionID = session.getID();
					return;
				}
			}else{
				session = sessionMgr.create();
				sessionID = session.getID();
			}
		}else{
			session = sessionMgr.create();
			sessionID = session.getID();
		}
		webForm.addCookie('sessionID', sessionID+"_"+session.getRefreshTime());
		webForm.setSession(session);
		webForm.setReqCookies(cookie);
		webForm.setContext(context);
		
		httpHandler.handleDynamicFile(req, res, webForm);
	});
	if (socket == 'on') {
		var io = sio.listen(server, {'log level': 0});
		io.set('authorization', function(handshakeData, callback){
			// 通过客户端的cookie字符串来获取其session数据
			var cookieStr = handshakeData.headers.cookie;
			if(cookieStr){
				handshakeData.cookie = appUtil.parseCookie(cookieStr);
				var sessionID = handshakeData.cookie.sessionID;
				var session;
				if(sessionID){//判断sessionid是否合法
					sessionID = sessionID.split('_')[0];
					session = sessionMgr.getSession(sessionID);
					var lastTime = sessionID.split('_')[1];
					sessionID = sessionID.split('_')[0];
					session = sessionMgr.getSession(sessionID);
					if(session){
						if(session.getRefreshTime()==lastTime){//判断时间戳是否合法，并将新的时间戳更新到cookie
							session.refresh();
						}else{//时间戳不对，session非法。
							sessionMgr.remove(sessionID);
							console.log('session非法！ip:');
	//						console.log('session非法！ip:'+clientIP);
							//handlerError({title:'session非法', msg:'session非法，请重新登录！'}, res);
							session = sessionMgr.create();
							sessionID = session.getID();
							return;
						}
					}else{
						session = sessionMgr.create();
						sessionID = session.getID();
					}
				}else{
					session = sessionMgr.create();
					sessionID = session.getID();
				}
				if(session){
					handshakeData.session = session;
				}else{
				}
			}
			callback(null, true);
		});
		server.listen(port);
		console.log('socket started');
	}
	
	io.sockets.on('connection', function(socket) {
		var socketServices = config.socketServices;
		var session = socket.handshake.session;
		function EventHandler(service){
			this.webForm = route.getWebForm(service.action);
			this.webForm.setSession(session);
			var controllerPath = path.join(this.webForm.getAppPath(), this.webForm.getControllerName());
			var controller = require("../" + controllerPath);
			var actionName = this.webForm.getActionName();
			this.action = controller[actionName];
			var instance = this;
			return function(data){
				instance.webForm.addAllParam(data);
				var ret = instance.action(instance.webForm);
				if(ret && ret['event']){
					socket.emit(ret['event'], instance.webForm.getData());
				}else{
					socket.send(data);
				}
			};
		}
		socketServices.each(function(){
			socket.on(this.event, new EventHandler(this));
		});
		socket.on('error', function(error){console.log(error);});
	});

	console.log('Server running at http://127.0.0.1:' + port + '/');
	util.debug('starting debug...');
};

//process.on('uncaughtException', function(err) {
//	console.log(err);
//});
